import jwt, { SignOptions } from 'jsonwebtoken';
import { Request, Response, NextFunction } from 'express';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

/**
 * JWT载荷接口
 */
interface JwtPayload {
  userId: number;
  idNumber: string;
  [key: string]: any;
}

/**
 * 扩展Request接口以包含用户信息
 */
declare global {
  namespace Express {
    interface Request {
      userId?: number;
      user?: any;
      admin?: { id: string; username: string };
    }
  }
}

/**
 * JWT认证中间件
 * 验证请求头中的token，并将用户信息添加到req中
 */
export const authMiddleware = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      res.status(401).json({
        success: false,
        message: '액세스 토큰이 없습니다.'
      });
      return;
    }

    // 验证token
    const JWT_SECRET = process.env.JWT_SECRET || 'korea-financial-system-secret-key';
    const decoded = jwt.verify(token, JWT_SECRET) as JwtPayload;
    
    // 查询用户信息
    const user = await prisma.user.findUnique({
      where: { id: decoded.userId },
      select: {
        id: true,
        idNumber: true,
        name: true,
        status: true
      }
    });

    if (!user) {
      res.status(401).json({
        success: false,
        message: '사용자를 찾을 수 없습니다.'
      });
      return;
    }

    if (user.status !== 'ACTIVE') {
      res.status(401).json({
        success: false,
        message: '계정이 정지되었습니다.'
      });
      return;
    }

    // 将用户信息添加到请求对象中
    req.userId = user.id;
    req.user = user;
    
    next();
  } catch (error: any) {
    console.error('토큰 검증 실패:', error.message);
    
    if (error.name === 'JsonWebTokenError') {
      res.status(401).json({
        success: false,
        message: '유효하지 않은 액세스 토큰입니다.'
      });
      return;
    }
    
    if (error.name === 'TokenExpiredError') {
      res.status(401).json({
        success: false,
        message: '액세스 토큰이 만료되었습니다.'
      });
      return;
    }
    
    res.status(500).json({
      success: false,
      message: '서버 내부 오류가 발생했습니다.'
    });
  }
};

